using AdmissionQA.Application.Common;
using AdmissionQA.Application.Dtos.QAHistory;
using AdmissionQA.Application.ServiceInterfaces;
using AdmissionQA.Domain.Entities;
using AdmissionQA.Domain.Repositorys;
using Microsoft.Extensions.Logging;

namespace AdmissionQA.Application.Services;

/// <summary>
/// 问答历史记录服务实现
/// </summary>
public class QAHistoryServices(IRepository<QAHistory> repository, ILogger<QAHistoryServices> logger, ITextEmbeddingService embeddingService)
    : IQAHistoryServices
{
    private readonly IRepository<QAHistory> _repository = repository;
    private readonly ILogger<QAHistoryServices> _logger = logger;
    private readonly ITextEmbeddingService _embeddingService = embeddingService;

    /// <summary>
    /// 创建问答历史记录
    /// </summary>
    /// <param name="qaHistory">问答历史记录</param>
    /// <returns>创建结果</returns>
    public async Task<Result<string>> CreateQAHistoryAsync(QAHistoryDto qaHistory)
    {
        try
        {
            var entity = QAHistory.CreateQAHistory(
                qaHistory.Query,
                qaHistory.Answer,
                qaHistory.QueryType,
                qaHistory.Confidence,
                qaHistory.UserIP,
                qaHistory.UserAgent
            );

            // 生成查询向量
            entity.QueryEmbedding = _embeddingService.GetVector(qaHistory.Query);

            await _repository.CreateAsync(entity);
            _logger.LogInformation("创建问答历史记录成功，查询：{Query}", qaHistory.Query);
            return Result<string>.Success("创建成功");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "创建问答历史记录失败，参数：{@QAHistory}", qaHistory);
            return Result<string>.Fail("创建问答历史记录失败");
        }
    }

    /// <summary>
    /// 批量创建问答历史记录
    /// </summary>
    /// <param name="qaHistories">问答历史记录列表</param>
    /// <returns>创建结果</returns>
    public async Task<Result<string>> CreateQAHistoriesAsync(QAHistoriesDto qaHistories)
    {
        try
        {
            var entities = new List<QAHistory>();
            foreach (var item in qaHistories.QAHistories)
            {
                var entity = QAHistory.CreateQAHistory(
                    item.Query,
                    item.Answer,
                    item.QueryType,
                    item.Confidence,
                    item.UserIP,
                    item.UserAgent
                );

                // 生成查询向量
                entity.QueryEmbedding = _embeddingService.GetVector(item.Query);
                entities.Add(entity);
            }

            await _repository.CreateRangeAsync(entities);
            _logger.LogInformation("批量创建问答历史记录成功，数量：{Count}", entities.Count);
            return Result<string>.Success("创建成功");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "批量创建问答历史记录失败");
            return Result<string>.Fail("批量创建问答历史记录失败");
        }
    }

    /// <summary>
    /// 获取所有问答历史记录
    /// </summary>
    /// <returns>问答历史记录列表</returns>
    public async Task<Result<IEnumerable<QAHistory>>> GetAllQAHistoriesAsync()
    {
        var histories = await _repository.GetAllAsync();
        return Result<IEnumerable<QAHistory>>.Success(histories);
    }

    /// <summary>
    /// 分页获取问答历史记录
    /// </summary>
    /// <param name="pageIndex">页码</param>
    /// <param name="pageSize">页大小</param>
    /// <returns>分页结果</returns>
    public async Task<Result<IEnumerable<QAHistory>>> GetPagedQAHistoriesAsync(int pageIndex = 0, int pageSize = 10)
    {
        var histories = await _repository.GetPagedAsync(pageIndex, pageSize);
        return Result<IEnumerable<QAHistory>>.Success(histories);
    }

    /// <summary>
    /// 根据查询类型获取问答历史记录
    /// </summary>
    /// <param name="queryType">查询类型</param>
    /// <returns>问答历史记录列表</returns>
    public async Task<Result<IEnumerable<QAHistory>>> GetQAHistoriesByTypeAsync(string queryType)
    {
        var histories = await _repository.GetListConditionAsync(item => item.QueryType == queryType);
        return Result<IEnumerable<QAHistory>>.Success(histories);
    }

    /// <summary>
    /// 根据置信度获取问答历史记录
    /// </summary>
    /// <param name="confidence">置信度</param>
    /// <returns>问答历史记录列表</returns>
    public async Task<Result<IEnumerable<QAHistory>>> GetQAHistoriesByConfidenceAsync(string confidence)
    {
        var histories = await _repository.GetListConditionAsync(item => item.Confidence == confidence);
        return Result<IEnumerable<QAHistory>>.Success(histories);
    }

    /// <summary>
    /// 获取问答历史记录数量
    /// </summary>
    /// <returns>数量</returns>
    public async Task<int> GetQAHistoryCountAsync()
    {
        return await _repository.GetCountAsync();
    }

    /// <summary>
    /// 删除问答历史记录
    /// </summary>
    /// <param name="id">记录ID</param>
    /// <returns>删除结果</returns>
    public async Task<Result<string>> DeleteQAHistoryAsync(Guid id)
    {
        var history = await _repository.GetByIdAsync(id);
        if (history == null)
        {
            _logger.LogWarning("删除问答历史记录失败：未找到记录，id={Id}", id);
            return Result<string>.Fail("没有找到问答历史记录");
        }

        if (!history.Delete())
        {
            _logger.LogWarning("删除问答历史记录失败：记录已被删除，id={Id}", id);
            return Result<string>.Fail("问答历史记录已经被删除");
        }

        await _repository.UpdateAsync(history);
        _logger.LogInformation("删除问答历史记录成功，id={Id}", id);
        return Result<string>.Success("删除成功");
    }

    /// <summary>
    /// 批量删除问答历史记录
    /// </summary>
    /// <param name="ids">记录ID列表</param>
    /// <returns>删除结果</returns>
    public async Task<Result<string>> DeleteQAHistoriesAsync(IEnumerable<Guid> ids)
    {
        var tasks = ids.Select(id => _repository.GetByIdAsync(id));
        var histories = await Task.WhenAll(tasks);
        var validHistories = histories.OfType<QAHistory>().ToList();

        if (validHistories.Count == 0)
        {
            _logger.LogWarning("批量删除问答历史记录失败：未找到任何记录，ids={@Ids}", ids);
            return Result<string>.Fail("没有找到问答历史记录");
        }

        foreach (var history in validHistories)
        {
            if (!history.Delete())
            {
                _logger.LogWarning("批量删除问答历史记录时，记录已被删除，id={Id}", history.Id);
                return Result<string>.Fail($"问答历史记录 {history.Id} 已经被删除");
            }
        }

        await _repository.UpdateRangeAsync(validHistories);
        _logger.LogInformation("批量删除问答历史记录成功，数量：{Count}", validHistories.Count);
        return Result<string>.Success("删除成功");
    }

    /// <summary>
    /// 获取热门查询（按查询次数排序）
    /// </summary>
    /// <param name="topK">返回前K个</param>
    /// <returns>热门查询列表</returns>
    public async Task<Result<IEnumerable<object>>> GetPopularQueriesAsync(int topK = 10)
    {
        try
        {
            var allHistories = await _repository.GetAllAsync();
            var popularQueries = allHistories
                .GroupBy(h => h.Query)
                .Select(g => new
                {
                    Query = g.Key,
                    Count = g.Count(),
                    LastQueryTime = g.Max(h => h.CreatedAt),
                    QueryType = g.First().QueryType,
                    Confidence = g.First().Confidence
                })
                .OrderByDescending(x => x.Count)
                .Take(topK)
                .ToList();

            return Result<IEnumerable<object>>.Success(popularQueries);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取热门查询失败");
            return Result<IEnumerable<object>>.Fail("获取热门查询失败");
        }
    }

    /// <summary>
    /// 获取查询统计信息
    /// </summary>
    /// <returns>统计信息</returns>
    public async Task<Result<object>> GetQueryStatisticsAsync()
    {
        try
        {
            var allHistories = await _repository.GetAllAsync();
            var totalQueries = allHistories.Count();
            
            // 使用东8区时间
            var now = DateTime.UtcNow.AddHours(8); // 获取东8区时间
            var todayQueries = allHistories.Count(h => h.CreatedAt.AddHours(8).Date == now.Date);
            var thisWeekQueries = allHistories.Count(h => h.CreatedAt.AddHours(8) >= now.AddDays(-7));
            var thisMonthQueries = allHistories.Count(h => h.CreatedAt.AddHours(8) >= now.AddMonths(-1));

            var typeStats = allHistories
                .GroupBy(h => h.QueryType)
                .Select(g => new
                {
                    QueryType = g.Key,
                    Count = g.Count(),
                    Percentage = Math.Round((double)g.Count() / totalQueries * 100, 2)
                })
                .OrderByDescending(x => x.Count)
                .ToList();

            var confidenceStats = allHistories
                .GroupBy(h => h.Confidence)
                .Select(g => new
                {
                    Confidence = g.Key,
                    Count = g.Count(),
                    Percentage = Math.Round((double)g.Count() / totalQueries * 100, 2)
                })
                .OrderByDescending(x => x.Count)
                .ToList();

            // 1. 一天24小时的问答数（今天，东8区）
            var today = now.Date;
            var hourlyStats = Enumerable.Range(0, 24)
                .Select(hour => new {
                    hour,
                    count = allHistories.Count(h => h.CreatedAt.AddHours(8).Date == today && h.CreatedAt.AddHours(8).Hour == hour)
                }).ToList();

            // 2. 一个星期的每日问答数（最近7天，东8区）
            var todayDate = now.Date;
            var weeklyStats = Enumerable.Range(0, 7)
                .Select(i => {
                    var date = todayDate.AddDays(-6 + i);
                    return new {
                        date = date.ToString("yyyy-MM-dd"),
                        count = allHistories.Count(h => h.CreatedAt.AddHours(8).Date == date)
                    };
                }).ToList();

            // 3. 一个月每4周的问答数（最近28天，分4周，东8区）
            var monthStart = todayDate.AddDays(-27); // 4周前
            var monthlyStatsByWeek = Enumerable.Range(0, 4)
                .Select(week => {
                    var weekStart = monthStart.AddDays(week * 7);
                    var weekEnd = weekStart.AddDays(6);
                    return new {
                        week = week + 1,
                        count = allHistories.Count(h => h.CreatedAt.AddHours(8).Date >= weekStart && h.CreatedAt.AddHours(8).Date <= weekEnd)
                    };
                }).ToList();

            // 4. 12个月的问答数（本年，东8区）
            var year = now.Year;
            var yearlyStats = Enumerable.Range(1, 12)
                .Select(month => {
                    var monthStartDate = new DateTime(year, month, 1);
                    var monthEndDate = monthStartDate.AddMonths(1).AddDays(-1);
                    return new {
                        month = monthStartDate.ToString("yyyy-MM"),
                        count = allHistories.Count(h => h.CreatedAt.AddHours(8).Date >= monthStartDate && h.CreatedAt.AddHours(8).Date <= monthEndDate)
                    };
                }).ToList();

            // 兼容前端dailyStats（最近30天每日数据，东8区）
            var dailyStats = Enumerable.Range(0, 30)
                .Select(i => {
                    var date = todayDate.AddDays(-29 + i);
                    return new {
                        date = date.ToString("yyyy-MM-dd"),
                        count = allHistories.Count(h => h.CreatedAt.AddHours(8).Date == date)
                    };
                }).ToList();

            var statistics = new
            {
                TotalQueries = totalQueries,
                TodayQueries = todayQueries,
                ThisWeekQueries = thisWeekQueries,
                ThisMonthQueries = thisMonthQueries,
                TypeStatistics = typeStats,
                ConfidenceStatistics = confidenceStats,
                AverageQueriesPerDay = totalQueries > 0 ? Math.Round((double)totalQueries / Math.Max(1, (now - allHistories.Min(h => h.CreatedAt.AddHours(8))).Days), 2) : 0,
                // 新增统计
                HourlyStats = hourlyStats,
                WeeklyStats = weeklyStats,
                MonthlyStatsByWeek = monthlyStatsByWeek,
                YearlyStats = yearlyStats,
                DailyStats = dailyStats
            };

            return Result<object>.Success(statistics);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取查询统计信息失败");
            return Result<object>.Fail("获取查询统计信息失败");
        }
    }
} 